<template>
  <div class="dt-upload">
    <div class="images-list">
      <el-upload
        class="upload-demo"
        :class="{hideUpload:hideUploadEdit}"
        :action="uploadUrl"
        :before-upload="handleBeforeUpload"
        :on-success="handleSuccess"
        :on-error="handleUploadError"
        :on-remove="handleRemove"
        :on-preview="handlePreview"
        :on-exceed="handleExceed"
        :on-change="handleChange"
        :file-list="fileList"
        :multiple="fileLimit > 1"
        :headers="headers"
        :data="paramsData"
        :limit="fileLimit"
        :disabled="disabled"
        :list-type="listType"
      >
        <i v-if="listType === 'picture-card'" class="el-icon-plus" />
        <el-button v-else size="small" type="primary">点击上传</el-button>
        <div v-if="showTip" slot="tip" class="el-upload__tip">只能上传 <b style="color: #f56c6c">{{ fileTypeName || 'jpg/png' }}</b> 文件，且不超过 <b style="color: #f56c6c">{{ fileSize }}MB</b></div>
        <div v-if="showTip" slot="tip" class="el-upload__tip">建议尺寸 <b style="color: #f56c6c">200*200</b> 像素</div>
      </el-upload>
      <el-dialog :visible.sync="dialogVisible" title="图片预览" append-to-body>
        <img width="100%" :src="dialogImageUrl" alt="">
      </el-dialog>
    </div>
  </div>
</template>

<script>
import { getToken } from "@/utils/auth";
import emitter from 'element-ui/src/mixins/emitter'
export default {
  name: 'DtUpload',
  mixins: [emitter],
  props: {
    // 值
    value: [Array],
    // 大小限制(MB)
    fileSize: {
      type: Number,
      default: 5
    },
    // 文件类型, 例如["doc", "xls", "ppt", "txt", "pdf"]
    fileType: {
      type: Array,
      default: () => ['png', 'jpg', 'jpeg']
    },
    // 文件列表类型 text/picture/picture-card
    listType: {
      type: String,
      default: 'picture-card'
    },
    // 是否显示提示
    isShowTip: {
      type: Boolean,
      default: true
    },
    // 是否禁用
    disabled: {
      type: Boolean,
      default: false
    },
    // 最大允许上传个数
    fileLimit: {
      type: Number,
      default: 1
    }
  },
  data: function() {
    return {
      headers: { Authorization: "Bearer " + getToken() },
      dialogVisible: false,
      uploadUrl: process.env.VUE_APP_BASE_API + "/common/upload", // 上传地址，必填
      paramsData: {
        secretFlag: 'N'
      }, // 上传携带的参数，看需求要不要
      fileList: [],
      // 是否隐藏上传按钮
      hideUploadEdit: false,
      dialogImageUrl: ''
      // tempFileList: [] // 因为 fileList为只读属性，所以用了一个中间变量来进行数据改变的交互。
    }
  },
  computed: {
    // 是否显示提示
    showTip() {
      return this.isShowTip && (this.fileType || this.fileSize)
    },
    fileTypeName() {
      const typeName = []
      this.fileType.forEach(item => {
        typeName.push(item)
      })
      return typeName.join(',')
    },
    fileAccept() {
      let fileAccept = ''
      this.fileType.forEach(element => {
        fileAccept += `.${element},`
      })
      return fileAccept
    }
  },
  watch: {
    value: {
      handler: function(newVal, oldVa) {
        this.fileList = newVal || []
        this.hideUploadEdit = (this.fileList.length >= this.fileLimit)
        this.dispatch('ElFormItem', 'el.form.change', newVal)
      },
      immediate: true,
      deep: true
    },
    fileLimit: {
      handler: function(newVal, oldVa) {
        this.hideUploadEdit = (this.fileList.length >= this.fileLimit)
      },
      immediate: true,
      deep: true
    }
  },
  created() {
    this.fileList = JSON.parse(JSON.stringify(this.value)) || []
  },
  methods: {
    handlePreview(file) {
      this.dialogImageUrl = file.url
      this.dialogVisible = true
    },
    // 上传前校检格式和大小
    handleBeforeUpload(file) {
      // 校检文件类型
      if (this.fileType && file) {
        let fileExtension = ''
        if (file.name.lastIndexOf('.') > -1) {
          fileExtension = file.name.slice(file.name.lastIndexOf('.') + 1)
        }
        const isTypeOk = this.fileType.some((type) => {
          if (file.type.indexOf(type) > -1) return true
          if (fileExtension && fileExtension.indexOf(type) > -1) return true
          return false
        })
        if (!isTypeOk) {
          this.$message.error(`文件格式不正确, 请上传${this.fileType.join('/')}格式文件!`)
          return false
        }
      }
      // 校检文件大小
      if (this.fileSize && file) {
        const isLt = file.size / 1024 / 1024 < this.fileSize
        if (!isLt) {
          this.$message.error(`上传图片大小不能超过 ${this.fileSize} MB!`)
          return false
        }
      }
      // this.showScreenLoading()
      return true
    },
    handleUploadError(err) {
      console.log(err)
      this.$message.error(err.message)
    },
    // 文件个数超出
    handleExceed() {
      this.$message.error(`超出上传文件个数,请删除以后再上传!`)
    },
    // 文件上传成功的钩子
    handleSuccess(res, file, fileList) {
      this.$message.success('上传成功')
      // this.imageUrl = URL.createObjectURL(file.raw)
      this.changeFileList(fileList)
    },
    // 文件列表移除文件时的钩子
    handleRemove(file, fileList) {
      this.changeFileList(fileList)
      // 大于1张隐藏
      this.hideUploadEdit = (fileList.length >= this.fileLimit)
    },
    // el-upload改变方法
    handleChange(file, filelist) {
      // 大于1张隐藏
      this.hideUploadEdit = (filelist.length >= this.fileLimit)
    },
    // 文件列表改变的时候，更新组件的v-model的文的数据
    changeFileList(fileList) {
      const tempFileList = fileList.map(item => {
        const tempItem = {
          name: item.name,
          url: item.response ? item.response.url : item.url,
          fileId: item.response ? item.response.fileName : item.uid
        }
        return tempItem
      })
      this.$emit('input', tempFileList)
    }
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="scss">
.avatar{
  height: 100px;
  width: 100px;
}
.picture{
  height: 100%;
  width: 100%;
}
::v-deep .el-upload-list__item.is-ready {
display: none;
}
::v-deep .hideUpload {
  .el-upload.el-upload--picture-card {
    display: none;
  }
}
::v-deep .el-upload-list__item {
  transition: none !important;
}
</style>
